package com.ld.shieldsb.common.core.pattern;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.ld.shieldsb.common.core.util.StringUtils;

/**
 * 
 * 正则表达式工具类
 * 
 * @ClassName PatternUtil
 * @author 刘金浩
 * @date 2021年6月23日 上午11:00:38
 *
 */
public class PatternUtil {

    private PatternUtil() {
    }

    /**
     * 给定内容是否匹配正则
     * 
     * @param regex
     *            正则
     * @param content
     *            内容
     * @return 正则为null或者""则不检查，返回true，内容为null返回false
     */
    public static boolean isMatch(String regex, CharSequence content) {
        if (content == null) {
            // 提供null的字符串为不匹配
            return false;
        }

        if (StringUtils.isEmpty(regex)) {
            // 正则不存在则为全匹配
            return true;
        }

        final Pattern pattern = PatternPool.get(regex, Pattern.DOTALL);
        return isMatch(pattern, content);
    }

    /**
     * 给定内容是否匹配正则
     * 
     * @param pattern
     *            模式
     * @param content
     *            内容
     * @return 正则为null或者""则不检查，返回true，内容为null返回false
     */
    public static boolean isMatch(Pattern pattern, CharSequence content) {
        if (content == null || pattern == null) {
            // 提供null的字符串为不匹配
            return false;
        }
        return pattern.matcher(content).matches();
    }

    /**
     * 获得匹配的字符串匹配到的所有分组
     * 
     * @param pattern
     *            编译后的正则模式
     * @param content
     *            被匹配的内容
     * @return 匹配后得到的字符串数组，按照分组顺序依次列出，未匹配到返回空列表，任何一个参数为null返回null
     */
    public static List<String> getAllGroups(Pattern pattern, CharSequence content) {
        return getAllGroups(pattern, content, true);
    }

    /**
     * 获得匹配的字符串匹配到的所有分组
     * 
     * @param pattern
     *            编译后的正则模式
     * @param content
     *            被匹配的内容
     * @param withGroup0
     *            是否包括分组0，此分组表示全匹配的信息
     * @return 匹配后得到的字符串数组，按照分组顺序依次列出，未匹配到返回空列表，任何一个参数为null返回null
     */
    public static List<String> getAllGroups(Pattern pattern, CharSequence content, boolean withGroup0) {
        if (null == content || null == pattern) {
            return null;
        }

        ArrayList<String> result = new ArrayList<>();
        final Matcher matcher = pattern.matcher(content);
        if (matcher.find()) {
            final int startGroup = withGroup0 ? 0 : 1;
            final int groupCount = matcher.groupCount();
            for (int i = startGroup; i <= groupCount; i++) {
                result.add(matcher.group(i));
            }
        }
        return result;
    }

    /**
     * 获得匹配的字符串
     * 
     * @param regex
     *            匹配的正则
     * @param content
     *            被匹配的内容
     * @param groupIndex
     *            匹配正则的分组序号
     * @return 匹配后得到的字符串，未匹配返回null
     */
    public static String get(String regex, CharSequence content, int groupIndex) {
        if (null == content || null == regex) {
            return null;
        }
        final Pattern pattern = PatternPool.get(regex, Pattern.DOTALL);
        return get(pattern, content, groupIndex);
    }

    /**
     * 获得匹配的字符串，对应分组0表示整个匹配内容，1表示第一个括号分组内容，依次类推
     * 
     * @param pattern
     *            编译后的正则模式
     * @param content
     *            被匹配的内容
     * @param groupIndex
     *            匹配正则的分组序号，0表示整个匹配内容，1表示第一个括号分组内容，依次类推
     * @return 匹配后得到的字符串，未匹配返回null
     */
    public static String get(Pattern pattern, CharSequence content, int groupIndex) {
        if (null == content || null == pattern) {
            return null;
        }

        final Matcher matcher = pattern.matcher(content);
        if (matcher.find()) {
            return matcher.group(groupIndex);
        }
        return null;
    }

    /**
     * 取得内容中匹配的所有结果，获得匹配的所有结果中正则对应分组0的内容
     * 
     * @param regex
     *            正则
     * @param content
     *            被查找的内容
     * @return 结果列表
     * 
     */
    public static List<String> findAllGroup0(String regex, CharSequence content) {
        return findAll(regex, content, 0);
    }

    /**
     * 取得内容中匹配的所有结果，获得匹配的所有结果中正则对应分组1的内容
     * 
     * @param regex
     *            正则
     * @param content
     *            被查找的内容
     * @return 结果列表
     * 
     */
    public static List<String> findAllGroup1(String regex, CharSequence content) {
        return findAll(regex, content, 1);
    }

    /**
     * 取得内容中匹配的所有结果，获得匹配的所有结果中正则对应分组0的内容
     * 
     * @param pattern
     *            编译后的正则模式
     * @param content
     *            被查找的内容
     * @return 结果列表
     * 
     */
    public static List<String> findAllGroup0(Pattern pattern, CharSequence content) {
        return findAll(pattern, content, 0);
    }

    /**
     * 取得内容中匹配的所有结果，获得匹配的所有结果中正则对应分组1的内容
     * 
     * @param pattern
     *            编译后的正则模式
     * @param content
     *            被查找的内容
     * @return 结果列表
     */
    public static List<String> findAllGroup1(Pattern pattern, CharSequence content) {
        return findAll(pattern, content, 1);
    }

    /**
     * 取得内容中匹配的所有结果
     * 
     * @param pattern
     *            编译后的正则模式
     * @param content
     *            被查找的内容
     * @param group
     *            正则的分组
     * @return 结果列表
     * 
     */
    public static List<String> findAll(Pattern pattern, CharSequence content, int group) {
        return findAll(pattern, content, group, new ArrayList<String>());
    }

    /**
     * 取得内容中匹配的所有结果
     * 
     * @param regex
     *            正则
     * @param content
     *            被查找的内容
     * @param group
     *            正则的分组
     * @return 结果列表
     */
    public static List<String> findAll(String regex, CharSequence content, int group) {
        return findAll(regex, content, group, new ArrayList<String>());
    }

    /**
     * 取得内容中匹配的所有结果
     * 
     * @param <T>
     *            集合类型
     * @param regex
     *            正则
     * @param content
     *            被查找的内容
     * @param group
     *            正则的分组
     * @param collection
     *            返回的集合类型
     * @return 结果集
     */
    public static <T extends Collection<String>> T findAll(String regex, CharSequence content, int group, T collection) {
        if (null == regex) {
            return collection;
        }

        return findAll(Pattern.compile(regex, Pattern.DOTALL), content, group, collection);
    }

    /**
     * 取得内容中匹配的所有结果
     * 
     * @param <T>
     *            集合类型
     * @param pattern
     *            编译后的正则模式
     * @param content
     *            被查找的内容
     * @param group
     *            正则的分组
     * @param collection
     *            返回的集合类型
     * @return 结果集
     */
    public static <T extends Collection<String>> T findAll(Pattern pattern, CharSequence content, int group, T collection) {
        if (null == pattern || null == content) {
            return null;
        }

        if (null == collection) {
            throw new NullPointerException("Null collection param provided!");
        }

        final Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            collection.add(matcher.group(group));
        }
        return collection;
    }
}
